QCODE.TXT:
Series 3/3a/3c/Workabout Q-code bytes 30/4/93, Jan. 94; revised Sep. 97.
Series 5 (OPL32) changes made March 1999.
All the information in this file and in MKTABLE.OPL was deduced
by Mike Rudin by analysing .OPO and .OPA files, and used in writing Revtran.
As it was not supplied by Psion, it is subject to errors and omissions.
If you don't understand some of it, please try to find out the answer yourself
by translating fragments of OPL, looking at the resultant q-code with a
hex editor, and comparing it with the information below.
As a last resort, you can contact me at mrudin@cix.co.uk.

"TOS" means Top Of Stack, i.e. the item most recently pushed onto the stack.
"Drop" means pop an item off the stack and discard it.
See MKTABLE.OPL for details of parameter formats for each command/function.

00 push value of int. var addressed by next two bytes
01 push value of longint. var addressed by next two bytes
02 push value of real var addressed by next two bytes
03 push value of string var. addressed by next two bytes
04 push addr of int. var addressed by next two bytes
05 push addr of longint. var addressed by next two bytes
06 push addr of real var addressed by next two bytes
07 push addr of string var addressed by next two bytes
08 push value of external global or proc param int addressed by next two bytes
09 push value of external global or proc param longint addressed by next two bytes
0a push value of external global or proc param float addressed by next two bytes
0b push value of external global or proc param string addressed by next two bytes
0c push addr of external global int addressed by next two bytes
0d push addr of external global longint addressed by next two bytes
0e push addr of external global float addressed by next two bytes
0f push addr of external global string addressed by next two bytes

10 push TOSth element of var array of ints addressed by next two bytes
11 push TOSth element of var array of longints addressed by next two bytes
12 push TOSth element of var array of floats addressed by next two bytes
13 push TOSth element of var array of strings addressed by next two bytes
14 push addr of TOSth element in var array of ints addressed by next two bytes
15 push addr of TOSth element in var array of longints addressed by next two bytes
16 push addr of TOSth element in var array of floats addressed by next two bytes
17 push addr of TOSth element in var array of strings addressed by next two bytes
18 push TOSth element of ext. global array of ints addressed by next two bytes
19 push TOSth element of ext. global array of longints addressed by next two bytes
1a push TOSth element of ext. global array of floats addressed by next two bytes
1b push TOSth element of ext. global array of strings addressed by next two bytes
1c push addr of TOSth element in ext. global array of ints addressed by next two bytes
1d push addr of TOSth element in ext. global array of longints addressed by next two bytes
1e push addr of TOSth element in ext. global array of floats addressed by next two bytes
1f push addr of TOSth element in ext. global array of strings addressed by next two bytes
20nn push value of int field (named by TOS string) of data file with logname nn
21nn push value of longint field (named by TOS string) of data file with logname nn
22nn push value of float field (named by TOS string) of data file with logname nn
23nn push value of string field (named by TOS string) of data file with logname nn
24nn push addr of int field (named by TOS string) of data file with logname nn (e.g. INPUT).
25nn push addr of longint field (named by TOS string) of data file with logname nn (e.g. INPUT).
26nn push addr of float field (named by TOS string) of data file with logname nn (e.g. INPUT).
27nn push addr of string field (named by TOS string) of data file with logname nn (e.g. INPUT).
28 push next 2 bytes as literal int
29 push next 4 bytes as literal longint
2a push next 8 bytes as float
2b push following string (which starts with length-count byte)
2c ?
2d ?
2e ?
2f ?
30 Int '<' operator
31 LongInt '<' operator
32 Float '<' operator
33 String '<' operator
34 Int '<=' operator
35 LongInt '<=' operator
36 Float '<=' operator
37 String '<=' operator
38 Int '>' operator
39 LongInt '>' operator
3a Float '>' operator
3b String '>' operator
3c Int '>=' operator
3d LongInt '>=' operator
3e Float '>=' operator
3f String '>=' operator
40 Int '=' (comparison) operator
41 LongInt '=' (comparison) operator
42 Float '=' (comparison) operator
43 String '=' (comparison) operator
44 Int '<>' operator
45 LongInt '<>' operator
46 Float '<>' operator
47 String '<>' operator
48 integer '+'
49 longint '+'
4a float '+'
4b string '+' concatenate
4c integer '-' subtract
4d longint '-' subtract
4e float '-' subtract
4f push next byte as positive literal int (0-127)
50 integer '*' multiply
51 longint '*' multiply
52 float '*' multiply
53 call procedure referenced by next two bytes (see note about params)
54 integer '/' divide
55 longint '/' divide
56 float '/' divide
5700 number ADDR (e.g. 04nnnn5700 for addr(a%))
5701 ASC
57020nn CALL with nn params (usu. 6)
5703 COUNT
5704 DAY
5705 DOW
5706 EOF
5707 ERR
5708 EXIST
5709 FIND
570a GET
570b IOA - uses ADDR for all three rtn. vars
570c IOW - uses ADDR for both rtn. vars.
570d IOOPEN - uses ADDR for handle variable
570e IOWRITE
570f IOREAD
5710 IOCLOSE
5711 IOWAIT
5712 HOUR
5713 KEY
5714 LEN
5715 LOC
5716 MINUTE
5717 MONTH
5718 PEEKB
5719 PEEKW
571a POS
571b RECSIZE
571c SECOND
571d USR
571e YEAR
571f string ADDR (e.g. 07nnnn571f for addr(str$))
5720 WEEK
5721 IOSEEK - uses ADDR for offset param.
5722 KMOD
5723 KEYA - uses ADDR for rtn vars: 04nnnn57004f0114nnnn57005723
5724 KEYC - uses ADDR
5725 IOOPEN for (var h%, addr%, mode%) form.  (4 params)
5726 gCREATE
5727 gCREATEBIT (params depend on OPL16/32)
572801 gLOADBIT(name$)
572802 gLOADBIT(name$,write%)
572803 gLOADBIT(name$,write%,i%)
5729 gLOADFONT
572a gRANK
572b gIDENTITY
572c gX
572d gY
572e gWIDTH
572f gHEIGHT
5730 gORIGINX
5731 gORIGINY
5732 gTWIDTH
5733 gPRINTCLIP
5734 TESTEVENT
5735nn OS with nn params (2 or 3)
5736 MENU
5737 DIALOG
57380nn ALERT with nn params
5739 gCREATE (3a)
573a MENU with param (3a)
573b CREATESPRITE (3a)
573c LOADLIB (3a)
573d UNLOADLIB (3a)
573e FINDLIB (3a)
573f GETLIBH (3a)
5740 DAYS
5741 IABS
5742 INT
5743 PEEKL
5744 SPACE
5745 DATETOSECS
5746 NEWOBJ (3a)
5747 NEWOBJH (3a)
5748 SEND (3a)
5749 ENTERSEND (3a)
574a ENTERSEND0 (3a)
574b ALLOC (3a)
574c REALLOC (3a)
574d ADJUSTALLOC (3a)
574e LENALLOC (3a)
574f IOC (3a)
5750 UADD (3a)
5751 USUB (3a)
5752 IOCANCEL (3a)
5753 STATWININFO (3a)
5754 FINDFIELD (3a)
5755 BOOKMARK (S5)
5756 GETEVENTC (S5)
5757 INTRANS (S5)
5758 mPOPUP (S5)
5780 ABS
5781 ACOS
5782 ASIN
5783 ATAN
5784 COS
5785 DEG
5786 EXP
5787 FLT
5788 INTF
5789 LN
578a LOG
578b PEEKF
578c PI
578d RAD
578e RND
578f SIN
5790 SQR
5791 TAN
5792 VAL
5793nn MAX with nn floats in list, or with a float array if nn = 0.
5794nn MEAN with nn as per MAX
5795nn MIN with nn as per MAX
5796nn STD with nn as per MAX
5797nn SUM with nn as per MAX
5798nn VAR with nn as per MAX
5799 EVAL
57c0 CHR$
57c1 DATIM$
57c2 DAYNAME$
57c3 DIR$
57c4 ERR$
57c5 FIX$
57c6 GEN$
57c7 GET$
57c8 HEX$
57c9 KEY$
57ca LEFT$
57cb LOWER$
57cc MID$
57cd MONTH$
57ce NUM$
57cf PEEK$
57d0 REPT$
57d1 RIGHT$
57d2 SCI$
57d3 UPPER$
57d4 USR$
57d5 GETCMD$
57d6 CMD$
57d7 PARSE$ - uses ADDR for rtn. var
57d8 ERRX$ (S5)
57d9 GETDOC$ (S5)
58 Integer '**' operator
59 LongInt '**' operator
5a Float '**' operator
5bnnnn jump rel if TOS is zero (used with comparisons, e.g. 40)
5c Int AND operator
5d LongInt AND operator
5e Float AND operator
5f Push next byte as positive literal longint
60 Int OR operator
61 LongInt OR operator
62 Float OR operator
63 Push next two bytes as positive (?) literal longint
64 Int NOT operator
65 LongInt NOT operator
66 Float NOT operator
67 ?
68 Int negate TOS, unary minus operator '-'
69 LongInt negate TOS, unary minus operator '-'
6a Float negate TOS, unary minus operator '-'
6bnnkk call proc. by name, @("str"): etc.;
   stack has name plus optional param-pairs;
   nn byte states no. of param-pairs pushed;
   kk char is '%','&',nul or '$' as appropriate.
6c percentage change operator a<b%       0
6d percentage previous operator a>b%     2
6e percentage addition operator a+b%     6
6f percentage subtract operator a-b%     7
70 percentage multiply operator a*b%     8
71 percentage divide operator a/b%       9
72 ?
73 ?
74 RETURN nothing (Int% proc)
75 RETURN nothing (LongInt& proc)
76 RETURN nothing (Float proc)
77 RETURN nothing (Str$ proc)
78 convert longint to int
79 convert float to Int
7a convert float to longint
7b convert int to longint
7c convert int to float
7d convert longint to float
7e convert?
7f convert?
80 DropInt - equiv to a command
81 DropLongInt
82 DropReal
83 DropString
84 store int  var%=val%
85 store longint
86 store real
87 store string
88 add integer to list for PRINT    PRINT i%;
89 add longint to list for PRINT
8a add float to list for PRINT
8b add string to list for PRINT 
8c add integer to list for LPRINT
8d add longint to list for LPRINT
8e add float to list for LPRINT
8f add string to list for LPRINT
90 add space to list for PRINT (as in ',' separator)
91 add space to list for LPRINT (as in ',' separator)
92 PRINT assembled list
93 LPRINT assembled list
94 INPUT an int
95 INPUT a longint
96 INPUT a float
97 INPUT a string
98 POKEW
99 POKEL
9a POKEF
9b POKE$
9c POKEB
9d APPEND
9e AT
9f BACK
a0 BEEP
a1 CLOSE
a2 CLS
a3 COMPRESS
a4 COPY
a5nn... CREATE (see note)
a600 CURSOR OFF
a601 CURSOR ON
a602 CURSOR id%
a603 CURSOR id%,asc%,width%,height%
a7 DELETE
a8 ERASE
a900 ESCAPE OFF
a901 ESCAPE ON
aa FIRST
abnnnn... VECTOR/ENDV with nnnn possible labels; rel. addresses
   follow for jumps from PC at 'ab' byte.
ac LAST
ad LCLOSE
ae LOADM
af LOPEN
b0 NEXT
b1nnnn ONERR; nnnn is label address rel. to
    'b1' byte, or 0000 for ONERR OFF.
b2 OFF (indefinite period)
b3 OFF (period specified)
b4nn... OPEN (see note)
b5 PAUSE
b6 POSITION
b7 IOSIGNAL
b8 RAISE
b9 RANDOMIZE
ba RENAME
bb STOP
bc TRAP (between args and relevant command)
bd UPDATE
benn USE logical name nn (00=A, 01=B, 02=C, 03=D)
bfnnnn GOTO... nnnn is relative address (add to
   PC when pointing to bf byte).  Label text is not stored.
c0 RETURN when variable specified (any type)
c1 UNLOADM
c2 EDIT
c3 SCREEN with two params (see e7)
c4nn... OPENR (see note)
c500 gSAVEBIT name$
c501 gSAVEBIT name$,width%,height%
c6 gCLOSE
c7 gUSE
c802 gSETWIN with 2 params
c804 gSETWIN with 4 params
c900 gVISIBLE OFF
c901 gVISIBLE ON
ca gFONT
cb gUNLOADFONT
cc gGMODE
cd gTMODE
ce gSTYLE
cf gORDER
d0 gINFO - same use of ADDR as GETEVENT
d1 gCLS
d2 gAT
d3 gMOVE
d4 gPRINT int
d5 gPRINT longint
d6 gPRINT float
d7 gPRINT string - list of expressions is split into sep. gPRINT statements
d8 equiv. to gPRINT " " - e.g. comma in gPRINT expr. list.
d901 gPRINTB with 2 params
..
d905 gPRINTB with 6 params
da gLINEBY
db gBOX
dc gCIRCLE (S5)
dd gELLIPSE (S5)
de gPOLY - ADDR used
df gFILL
e0 gPATT
e1 gCOPY
e202 gSCROLL with 2 params
e206 gSCROLL with 6 params
e300 gUPDATE OFF
e301 gUPDATE ON
e3ff gUPDATE
e4 GETEVENT  - ADDR is used; e.g. GETEVENT a%() -> 4f011414005700e4
e5 gLINETO
e6 gPEEKLINE - ADDR used for 4th param  (params depend on OPL16/32)
e7 SCREEN with four params (see c3)
e8 IOWAITSTAT - ADDR used for rtn. var
e9 IOYIELD
ea mINIT
ebnn mCARD with title and nn string/code pairs
ec00 dINIT
ec01 dINIT title$
ed0000 dTEXT p$,body$
ed0001 dTEXT p$,body$,t%
ed01 dCHOICE - ADDR not used
ed02 dLONG   - ADDR not used
ed03 dFLOAT  - ADDR not used
ed04 dTIME   - ADDR not used
ed05 dDATE   - ADDR not used
ed06 dEDIT var str$,p$        - ADDR not used
ed07 dEDIT var str$,p$,len$   - ADDR not used
ed08 dXINPUT - ADDR not used
ed09 dFILE   - ADDR not used
ed0ann dBUTTONS with nn string/int pairs (1, 2 or 3)
ed0b dPOSITION
ee SETNAME (not S5)
ef00 STATUSWIN OFF  (not S5)
ef01 STATUSWIN ON    (not S5)
ef02 STATUSWIN ON, n  (3a)  (not S5)
f00nn BUSY with nn params (1, 2 or 3), or BUSY OFF (nn = 0)
f100 LOCK OFF
f101 LOCK ON
f2 gINVERT
f3 gXPRINT
f401 gBORDER flags%
f403 gBORDER flags%,width%,height%
f500 gCLOCK OFF
f501 gCLOCK ON
f502 gCLOCK ON,mode%
f503 gCLOCK ON,mode%,offset%
f6nn value of calculator memory nn, e.g. M4
f7nn address of calculator memory nn, e.g. M4 
f8 MKDIR
f9 RMDIR
fa SETPATH
fb SECSTODATE - uses ADDR for all but 1st param
fc00 GIPRINT str$
fc01 GIPRINT str$,c%
fd
fe
ff00 gGREY (3a)
ff01 DEFAULTWIN (3a)
ff02 DIAMINIT (3a) (not S5)
ff03 DIAMPOS (3a) (not S5)
ff04 FONT (3a)
ff05 STYLE (3a)
ff06 USESPRITE (3a) (not S5)
ff07 APPENDSPRITE (3a) (not S5)
ff08 DRAWSPRITE (3a) (not S5)
ff09 CHANGESPRITE(3a) (not S5)
ff0a POSSPRITE (3a) (not S5)
ff0b CLOSESPRITE2 (3a) (not S5)
ff0c FREEALLOC (3a)
ff0d LINKLIB (3a) (not S5)
ff0e CACHE (3a) (not S5)
ff0f gBUTTON (3a) (params depend on OPL16/32)
ff10 gXBORDER (3a)
ff11 gDRAWOBJECT (3a) (not S5)
ff12 ODBINFO (3a) (not S5)
ff13 CACHETIDY (3a) (not S5)
ff14 SCREENINFO (3a)
ff15 CACHEHDR (3a) (not S5)
ff16 CACHEREC (3a) (not S5)
ff1700 dINITS (Workabout) (not S5)
ff1701 dINITS title$ (Workabout)
ff18 OPX Call (S5)
ff19 ?
ff1a MODIFY (S5)
ff1b INSERT (S5)
ff1c CANCEL (S5)
ff1d PUT (S5)
ff1e DELETE (S5)
ff1f GOTOMARK (S5)
ff20 KILLMARK (S5)
ff21 ?
ff22 GETEVENT32 (S5)
ff23 GETEVENTA32 (S5)
ff24 gCOLOR (S5)
ff25 SETFLAGS (S5)
ff26 SETDOC (S5)
ff27 DAYSTODATE (S5)
ff28 gINFO32 (S5)
ff29 IOWAITSTAT32 (S5)
ff2a COMPACT (S5)
ff2b BEGINTRANS (S5)
ff2c COMMITTRANS (S5)
ff2d ROLLBACK (S5)
ff2e CLEARFLAGS (S5)
ff2f POINTERFILTER (S5)
ff30 mCASC (S5)
ff31 ?
ff32 ?
ff33 dCHECKBOX (S5)
ff34 gSETPENWIDTH (S5)
ff35 dEDITMULTI (S5)

Note:
For CREATE, OPEN and OPENR:
File name string is expected TOS, then 1st byte after q-code is
desired logical name nn (00=A,01=B,02=C,03=D).  Following that
are the field names, each a string (including %,& etc) preceded
by typecode byte.
Following that is ff in place of typecode, to terminate list of names.
Source code syntax is odd; field names are interpreted as strings,
but quotes must not be present.


Params when calling procedures:
{push parameter, push type-code integer} for each param

BREAK, CONTINUE
DO..UNTIL
WHILE..ENDWH
IF-ELSEIF-ELSE-ENDIF
-all these constructs are implemented with conditional
and unconditional relative jumps (5bnnnn and bfnnnn).

The following commands/functions have at least one VAR parameter:
570b IOA - uses ADDR for 3rd, 4th & 5th params
570c IOW - uses ADDR for 3rd & 4th params.
570d IOOPEN - uses ADDR for 1st param
5721 IOSEEK - uses ADDR for offset (3rd) param.
5723 KEYA - uses ADDR for both params: 04nnnn57004f0114nnnn57005723
5724 KEYC - uses ADDR for param
57d7 PARSE$ - uses ADDR for rtn. var
d0 gINFO - same use of ADDR as GETEVENT
e4 GETEVENT  - ADDR is used; e.g. GETEVENT a%() -> 4f011414005700e4
e6 gPEEKLINE - ADDR used for 4th param
e8 IOWAITSTAT - ADDR used for param
ed01 dCHOICE to
..
ed09 dFILE  - ADDR used for 1st param in each?
fb SECSTODATE - uses ADDR for 7 params, i.e. all but 1st param
ff04 FONT (3a)
ff0701 APPENDSPRITE with 4 params (3a)
ff08 DRAWSPRITE (3a)
ff0901 CHANGESPRITE with 5 params (3a)
ff0a POSSPRITE (3a)
ff0b CLOSESPRITE (3a)
ff0c FREEALLOC (3a)
ff12 ODBINFO (3a)
ff14 SCREENINFO - ADDR used  (3a)
ff15 CACHEHDR (3a)
ff16 CACHEREC (3a)

[End of qcode.txt]
